package buy

import (
	"adam2/internal/model"
	"adam2/internal/properties"
	"adam2/internal/util"
	"anubis-framework/pkg/io"
	"gorm.io/gorm"
)

// 普通买入
type CommonBuy struct {
	db *gorm.DB
}

// 初始化
func (c *CommonBuy) Init(db *gorm.DB) {
	c.db = db
}

// 买入
func (c *CommonBuy) DoBuy(transactionDate string) {
	io.Infoln("买入")

	// 查询quant_account表的记录
	var quantAccountArray *model.QuantAccountArray
	c.db.Raw("select * from quant_account").Scan(&quantAccountArray)

	if quantAccountArray != nil && len(*quantAccountArray) > 0 {
		for _, quantAccount := range *quantAccountArray {

			var holdStockNumber int = quantAccount.HoldStockNumber
			// 如果某个账号的持股数量已经到达最大持股数量，则跳过这个账号
			if holdStockNumber >= properties.QuantProperties_.MaxHoldStockNumber {
				io.Infoln("账号[%s]的持股数量已经到达[%d]只，不再买入股票", quantAccount.AccountName, holdStockNumber)
				continue
			}

			// 查询quant_stock_filter表的记录，不包括quant_stock_transact_record表中还没有卖出的记录，也不包括当日是最后交易日的记录
			var quantStockFilterArray *model.QuantStockFilterArray
			c.db.Raw("select t.* from quant_stock_filter t where t.stock_code not in("+
				"select t1.stock_code from quant_stock_transact_record t1 "+
				"where t1.sell_date is null and t1.sell_price is null and t1.sell_amount is null) and "+
				"t.stock_code not in("+
				"select si_.code_ from stock_info si_ where si_.last_transaction_date=to_date(?,'yyyy-mm-dd')) "+
				"order by t.total_market_value asc, t.stock_code", transactionDate).Scan(&quantStockFilterArray)

			if quantStockFilterArray != nil && len(*quantStockFilterArray) > 0 {
				for _, quantStockFilter := range *quantStockFilterArray {

					// 查询股票记录
					var stockTransactionDataAll *model.StockTransactionDataAll
					c.db.Raw("select * from stock_transaction_data_all t where t.code_=? and t.date_=to_date(?,'yyyy-mm-dd')",
						quantStockFilter.StockCode, transactionDate).Scan(&stockTransactionDataAll)
					if stockTransactionDataAll == nil {
						io.Infoln("股票在日期[%s]没有交易记录，可能是停牌，从表quant_stock_filter表中删除这条记录，跳过这只股票", transactionDate)

						// 从quant_stock_filter表中删除这条记录
						c.db.Exec("delete from quant_stock_filter t where t.stock_code = ?", quantStockFilter.StockCode)

						continue
					}

					// 如果股票的收盘价过高，或者资金资产太少，连一手也买不了，则直接查找下一个机器人
					if util.CalculateBuyStockFee(quantStockFilter.StockCode, stockTransactionDataAll.OpenPrice, 100) > float64(quantAccount.CapitalAssets) {
						break
					}

					// 如果可以买，则向quant_stock_transact_record表中插入数据，从quant_stock_filter表中删除这条记录。
					// 计算应该买入股票的数量
					// quant_stock_filter表的记录数
					var quantStockFilterNumber int = -1
					c.db.Raw("select count(*) from quant_stock_filter").Scan(&quantStockFilterNumber)

					// 应当买入的股票的数量
					var shouldBuyStockNumber int = -1
					if quantStockFilterNumber <= (properties.QuantProperties_.MaxHoldStockNumber - quantAccount.HoldStockNumber) {
						shouldBuyStockNumber = quantStockFilterNumber
					} else {
						shouldBuyStockNumber = properties.QuantProperties_.MaxHoldStockNumber - quantAccount.HoldStockNumber
					}

					// 判断是否需要继续买入
					if shouldBuyStockNumber == 0 {
						io.Infoln("账号[%s]持股数量已经是%d，不再需要买入股票", quantAccount.AccountName, properties.QuantProperties_.MaxHoldStockNumber)
						break
					}

					// 计算买多少股
					// 买入多少股
					var buyOrSellAmount int = 100

					for quantAccount.CapitalAssets/float64(properties.QuantProperties_.MaxHoldStockNumber-quantAccount.HoldStockNumber) >= util.CalculateBuyStockFee(quantStockFilter.StockCode, stockTransactionDataAll.OpenPrice, buyOrSellAmount) {
						if util.CalculateBuyStockFee(quantStockFilter.StockCode, stockTransactionDataAll.OpenPrice, buyOrSellAmount) >= quantAccount.CapitalAssets/float64(properties.QuantProperties_.MaxHoldStockNumber-quantAccount.HoldStockNumber) {
							break
						}
						buyOrSellAmount = buyOrSellAmount + 100
					}
					if quantAccount.CapitalAssets/float64(properties.QuantProperties_.MaxHoldStockNumber-quantAccount.HoldStockNumber) < util.CalculateBuyStockFee(quantStockFilter.StockCode, stockTransactionDataAll.OpenPrice, buyOrSellAmount) {
						if buyOrSellAmount == 100 {
							// 从quant_stock_filter表中删除这条记录
							c.db.Exec("delete from quant_stock_filter t where t.stock_code = ?", quantStockFilter.StockCode)

							continue
						} else {
							buyOrSellAmount = buyOrSellAmount - 100
						}
					}

					// 向表quant_stock_transact_record中插入记录
					c.db.Exec("insert into quant_stock_transact_record(ACCOUNT_NAME, STOCK_CODE, BUY_DATE, BUY_PRICE, BUY_AMOUNT, "+
						"REGISTRATION_FEE_WHEN_BUY, COMMISSION_WHEN_BUY) "+
						"values(?, ?, to_date(?, 'yyyy-mm-dd'), ?, ?, ?, ?)",
						quantAccount.AccountName, quantStockFilter.StockCode, transactionDate, stockTransactionDataAll.OpenPrice, buyOrSellAmount,
						util.CalculateRegistrationFee(quantStockFilter.StockCode, buyOrSellAmount),
						util.CalculateCommission(stockTransactionDataAll.OpenPrice, buyOrSellAmount))

					// 删除quant_stock_filter表中的记录
					c.db.Exec("delete from quant_stock_filter t where t.stock_code = ?", quantStockFilter.StockCode)

					// 更新账号的持股数量
					holdStockNumber = holdStockNumber + 1

					// 如果某个账号的持股数量已经到达最大持股数量，则跳过这个账号
					if holdStockNumber >= properties.QuantProperties_.MaxHoldStockNumber {
						io.Infoln("账号[%s]的持股数量已经到达[%d]只，不再买入股票", quantAccount.AccountName, holdStockNumber)
						break
					}
				}
			} else {
				io.Infoln("表quant_stock_filter中没有记录，不再买入股票")
			}
		}
	} else {
		io.Infoln("表quant_account中没有记录")
	}
}
